package com.alks.function.service.impl.chengKong;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.config.handler.EasyExcelHandler;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.UserInfoUtil;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.enums.CompanyEnum;
import com.alks.entity.data.enums.chengkong.DefineEnum;
import com.alks.entity.data.page.PageRecord;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.chengKong.produce.*;
import com.alks.function.data.request.chengKong.*;
import com.alks.function.mapper.SdCompanyMapper;
import com.alks.function.mapper.chengKong.PcOutListMapper;
import com.alks.function.mapper.produce.PcStitchBarcodeHeadMapper;
import com.alks.function.service.chengKong.PcOutListService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PcOutListServiceImpl implements PcOutListService {

    @Resource
    private PcOutListMapper pcOutListMapper;

    @Resource
    private PcStitchBarcodeHeadMapper pcStitchBarcodeHeadMapper;


    /**
     * 外发项目建档-外加工项目明细
     * @return
     */
    @Override
    public ResponseInfo getOutsourcedProjectsList() {
        List<PcOutListDto> outList = pcOutListMapper.getOutsourcedProjectsList();
        return ResponseInfo.ok(outList);
    }

    /**
     * 外发项目建档-建档作业插入
     * @return
     */
    @Override
    public ResponseInfo getOutsourcedProjectsAdd(Map<String, String> param) {
        String partName = param.get("partName");
        if (ObjectUtils.isEmpty(partName)){
            return ResponseInfo.error("请填写外加工项目名称!");
        }
        PcOutList pcOutList = new PcOutList();
        String companyId = UserIdThread.get().getCompanyId();
        String userName = UserIdThread.get().getUserName();
        pcOutList.setCompanyId(companyId);
        pcOutList.setSysUser(userName);
        pcOutList.setSysDate(LocalDateTime.now());
        pcOutList.setPartName(partName);
        pcOutListMapper.AddOutsourcedProjectsAdd(pcOutList);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 外发项目建档-修改是否预补
     * @param param
     * @param partSeq
     * @return
     */
    @Override
    public ResponseInfo getOutsourcedProjectsUpdate(Integer param, Integer partSeq) {
        if (param == null || partSeq == null){
            return ResponseInfo.error("param或partSeq参数为空!");
        }
        String userName = UserIdThread.get().getUserName();
        LocalDateTime dateTime = LocalDateTime.now();
        switch (param){
            case 0:
                pcOutListMapper.UpdateOutsourcedProjects(userName,dateTime,null, partSeq);
                break;
            case 1:
                String value = DefineEnum.CHECKOUT_FLAG.getValue();
                pcOutListMapper.UpdateOutsourcedProjects(userName,dateTime,value, partSeq);
                break;
            default:
                return ResponseInfo.error("参数错误!");
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 外发项目建档-删除
     * @param partSeq
     * @return
     */
    @Override
    public ResponseInfo getOutsourcedProjectsDel(Integer partSeq) {
        if (partSeq == null){
            return ResponseInfo.error("partSeq参数为空!");
        }
        pcOutListMapper.delOutsourcedProjects(partSeq);
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 选择外发项目
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getChooseOutsourcedProjects(LotNoToStyleRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())&&ObjectUtils.isEmpty(request.getStyle())){
            return ResponseInfo.error("请输入指令或型体!");
        }
        Map map = new HashMap<>();
        request.setCompanyId(UserIdThread.get().getCompanyId());
        List<PcLotHeadListDto> pcLotHeadList = pcOutListMapper.getPcLotHeadList(request);
        if (ObjectUtils.isEmpty(pcLotHeadList)){
            return ResponseInfo.error("请输入正确的指令/型体!");
        }
        PageInfo<PcLotHeadListDto> list = new PageInfo<>(pcLotHeadList);
        map.put("list",pcLotHeadList);
        map.put("total",list.getTotal());
        return ResponseInfo.ok(map);
    }

    /**
     * 选择外发指令查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getChooseOutgoingInstructionsList(LotNoRequest request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        //查询指令信息
        PcLotHead pcLotHead = pcOutListMapper.getPcLotHead(request.getLotNo(),companyId);
        if (ObjectUtils.isEmpty(pcLotHead)) {
            return ResponseInfo.error("请输入正确的指令/型体!");
        }

        Integer count = pcStitchBarcodeHeadMapper.getPcCostLot(request.getLotNo(),companyId);
        if (count != null && count > 0) {
            return ResponseInfo.error(request.getLotNo() + "指令成本已封账,不能处理!");
        }

        Map map = new HashMap<>();
        List<PcLotOutListDto> dtoList=new ArrayList<>();
        List<PcLotOutListDto> list = pcOutListMapper.getInstructionOutsourcing(request.getLotNo(),companyId);
        if (ObjectUtils.isEmpty(list)){
            return ResponseInfo.error("该指令外加工项目未审核/不存在!");
        }
        for (PcLotOutListDto t : list) {
            List<PcOutSizeListDto> sizeDetailList = pcOutListMapper.getSizeDetailList(request.getLotNo(), t.getPartName(),companyId);
            if (!ObjectUtils.isEmpty(sizeDetailList)) {
                for (PcOutSizeListDto pcOutSizeListDto : sizeDetailList) {
                    if (pcOutSizeListDto.getOutQty()!=null){
                        pcOutSizeListDto.setThisQty(pcOutSizeListDto.getOutQty());
                    }
                }
                t.setSizeList(sizeDetailList);
                dtoList.add(t);
            }
        }
        if (ObjectUtils.isEmpty(dtoList)){
            return ResponseInfo.error("该指令没有可外发的项目!");
        } else {
            map.put(request.getLotNo(), dtoList);
            String photo = pcOutListMapper.getPhoto(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            map.put("photo", photo);
            return ResponseInfo.ok(map);
        }
    }

    /**
     * 生成外发资料
     * @param request
     * @param type 0 冲裁外发 1 工艺外发  2 补单外发 3 指令外发
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo GenerateOutsourcedMaterials(GenerateOutsourcedMaterialsRequest request, int type) {
        if (ObjectUtils.isEmpty(request.getOutList())){
            return ResponseInfo.error("请选择外发指令!");
        }

        //判断是否都存在号码
        for (OutGoingRequest outGoingRequest : request.getOutList()) {
            if (ObjectUtils.isEmpty(outGoingRequest.getNumberList())){
                return ResponseInfo.error("请选择号码!");
            }
        }
        String value = CompanyEnum.updateId(UserIdThread.get().getCompanyId());
        switch (type) {
            case 0:
                value = getMaxReqNo(value+DefineEnum.W_F.getValue());
                insertOutListDetail(request, value, type);
                break;
            case 1:
                value = getMaxReqNo(value+DefineEnum.W_H.getValue());
                insertOutListDetail(request, value, type);
                break;
            case 2:
                if (ObjectUtils.isEmpty(request.getReqNo())){
                    return ResponseInfo.error("补料单号不能为空!");
                }
                value=request.getReqNo();
                insertOutListDetail(request, value, type);
                break;
            case 3:
                value = getMaxReqNo(value+DefineEnum.W_X.getValue());
                insertOutListDetail(request, value, type);
                break;
            default:
                return ResponseInfo.error("请选择正确的操作!");
        }
        return ResponseInfo.ok("操作成功!");
    }

    /**
     * 插入外发信息
     * @param request
     * @param result
     * @param type
     */
    private void insertOutListDetail(GenerateOutsourcedMaterialsRequest request, String result, int type) {
        for (OutGoingRequest outGoingRequest : request.getOutList()) {
            PcOutListDetail pcOutListDetail = new PcOutListDetail();
            String companyId = UserIdThread.get().getCompanyId();
            String userName = UserIdThread.get().getLoginName();
            pcOutListDetail.setCompanyId(companyId);
            pcOutListDetail.setLotNo(outGoingRequest.getLotNo());
            pcOutListDetail.setStyle(outGoingRequest.getStyle());
            pcOutListDetail.setColor(outGoingRequest.getColor());
            pcOutListDetail.setSeqNo(outGoingRequest.getSeqNo());
            pcOutListDetail.setPartName(outGoingRequest.getPartName());
            pcOutListDetail.setSysDate(LocalDateTime.now());
            pcOutListDetail.setSysUser(userName);
            pcOutListDetail.setReqNo(result);
            pcOutListDetail.setPurQty(outGoingRequest.getTotalQty());
            pcOutListDetail.setPurDate(outGoingRequest.getPurDate());
            pcOutListDetail.setPrice(outGoingRequest.getPrice());
            pcOutListDetail.setVendor(outGoingRequest.getVendor());
            pcOutListDetail.setAmt(outGoingRequest.getPrice().multiply(outGoingRequest.getTotalQty()));
            pcOutListDetail.setOutDispatchType(new BigDecimal(type));
            pcOutListDetail.setSubSurplusFlag(outGoingRequest.getSubSurplusFlag());
            pcOutListDetail.setProcess(outGoingRequest.getProcess());
            pcOutListDetail.setCutNum(outGoingRequest.getCutNum());
            pcOutListDetail.setPurMemo(outGoingRequest.getPurMemo());
            pcOutListMapper.addPcOutListDetail(pcOutListDetail);

            List<PcOutListDetailSize> list = outGoingRequest.getNumberList().stream().map(s -> {
                PcOutListDetailSize pcOutListDetailSize = new PcOutListDetailSize();
                pcOutListDetailSize.setCompanyId(companyId);
                pcOutListDetailSize.setLotNo(outGoingRequest.getLotNo());
                pcOutListDetailSize.setPartName(outGoingRequest.getPartName());
                pcOutListDetailSize.setSizeNo(s.getSizeNo());
                pcOutListDetailSize.setQty(s.getThisQty());
                pcOutListDetailSize.setSeqNo(s.getSeqNo());
                pcOutListDetailSize.setReqNo(result);
                pcOutListDetailSize.setProcess(outGoingRequest.getProcess());
                return pcOutListDetailSize;
            }).collect(Collectors.toList());
            pcOutListMapper.addPcOutListDetailSize(list);
        }
    }

    /**
     * 生成ReqNo
     * @param value
     * @return
     */
    private String getMaxReqNo(String value){
        String MaxReqNo = pcOutListMapper.getReqNo(value);
        if (ObjectUtils.isEmpty(MaxReqNo)){
            MaxReqNo= "0";
        }
        Integer newMaxReqNo = Integer.parseInt(MaxReqNo)+1;
        String result = String.format("%08d", newMaxReqNo);
        result=value+result;
        return result;
    }

    /**
     * 外发明细
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getOutsourcedDetailsList(OutGoingQueryRequest request) {
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        String loginName = userInfo.getLoginName();
        String companyId = userInfo.getCompanyId();
        List<PcOutListDetailDto> outsourcedDetailsList = pcOutListMapper.getOutsourcedDetailsList(request,loginName,companyId);
        if (!ObjectUtils.isEmpty(outsourcedDetailsList)){
            for (PcOutListDetailDto pcOutListDetailDto : outsourcedDetailsList) {
                if (!ObjectUtils.isEmpty(pcOutListDetailDto.getCfmFlag())){
                    pcOutListDetailDto.setCfmFlag("已检验");
                }
            }
        }
        PageRecord<PcOutListDetailDto> list = new PageRecord<>();
        list.setList(outsourcedDetailsList);
        PageInfo pageInfo = new PageInfo(outsourcedDetailsList);
        list.setTotal(pageInfo.getTotal());
        return ResponseInfo.ok(list);
    }

    /**
     * 外发号码明细
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getOutsourcedNumberDetailsList(OutGoingNumberQueryRequest request) {
        request.setCompanyId(UserIdThread.get().getCompanyId());
        List<PcOutDetailSizeDto> outsourcedNumberDetailsList = pcOutListMapper.getOutsourcedNumberDetailsList(request);
        return ResponseInfo.ok(outsourcedNumberDetailsList);
    }

    @Resource
    private RedisService redisService;

    /**
     * 形成外加工单
     * @param request
     * @return
     */
    @Override
    public ResponseInfo getFormAnExternalProcessingOrder(OutGoingOrderRequest request) {
        if (ObjectUtils.isEmpty(request.getIds())){
            return ResponseInfo.error("请选择记录!");
        }
        if (ObjectUtils.isEmpty(request.getDeliveryDate())){
            return ResponseInfo.error("请选择交期!");
        }
        String value = CompanyEnum.updateId(UserIdThread.get().getCompanyId());
        String slipNo = redisService.slipNoGenerate(value+DefineEnum.W_F.getValue(), 3,1);
        List<PcOutListDetail> updateList = request.getIds().stream().map(s -> {
            PcOutListDetail pcOutListDetail = new PcOutListDetail();
            pcOutListDetail.setId(s);
            pcOutListDetail.setSlipNo(slipNo);
            pcOutListDetail.setDeliveryDate(request.getDeliveryDate());
            return pcOutListDetail;
        }).collect(Collectors.toList());
        pcOutListMapper.updatePcOutListDetail(updateList);
        if (!ObjectUtils.isEmpty(request.getNumberList())){
            pcOutListMapper.updatePcOutListDetailSize(request.getNumberList(),slipNo);
        }
        return ResponseInfo.ok("成功形成外发单,外发单号:"+slipNo);
    }

    /**
     * 整个加工单删除
     * @param slipNo
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo DeleteTheEntireAdditionalOrder(String slipNo) {
        List<PcOutListDetailDto> pcOutListDetail = pcOutListMapper.getPcOutListDetail(slipNo);
        if (ObjectUtils.isEmpty(pcOutListDetail)){
            return ResponseInfo.error("外发单号为空或查询数据为空,不可删除!");
        }
        for (PcOutListDetailDto t : pcOutListDetail) {
            if (!ObjectUtils.isEmpty(t.getCfmFlag())){
                return ResponseInfo.error("财务已检核,不能删除!");
            }
        }
        pcOutListMapper.delPcOutListDetail(slipNo);
        pcOutListMapper.delPcOutListDetailSize(pcOutListDetail);
        return ResponseInfo.ok("操作成功!");
    }

    @Resource
    private SdCompanyMapper sdCompanyMapper;

    /**
     * 导出合同
     * @param slipNo
     * @param response
     */
    @Override
    public void ExportContract(String slipNo, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(slipNo)){
            throw new SecurityException("外发单号不能为空!");
        }
        List<PcOutListDetailDto> list = pcOutListMapper.getPcOutListDetail(slipNo);
        if (ObjectUtils.isEmpty(list)){
            throw new SecurityException("没有加工明细不可导出!");
        }
        BigDecimal count=BigDecimal.ZERO;
        String vendor="";
        LocalDate deliveryDate=null;
        int id=1;
        for (PcOutListDetailDto t : list) {
            if (t.getPurDate()!=null){
                count=count.add(t.getPurQty());
            }
            if (!ObjectUtils.isEmpty(t.getVendor())){
                vendor=t.getVendor();
            }
            if (t.getDeliveryDate()!=null){
                deliveryDate=t.getDeliveryDate();
            }
            if (!ObjectUtils.isEmpty(t.getProcess())){
                t.setPartName(t.getProcess()+t.getPartName());
            }
            t.setId(id++);
        }
        SdCompany info = sdCompanyMapper.findAllBYCompanyId(UserIdThread.get().getCompanyId());
        String fileName = "外发加工单" + DateUtils.dateTimeNow() + ".xls";
        try (
                InputStream inputStream = new ClassPathResource("templates/外发加工单合同模板.xlsx").getInputStream();
                OutputStream outputStream = response.getOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream).excelType(ExcelTypeEnum.XLSX).withTemplate(inputStream).build();
        ) {
            ExcelUtils.setResponseZF(response, fileName);
            WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(new EasyExcelHandler()).build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            Map<Object, Object> map = new HashMap<>();
            map.put("chiName",info.getChiName());
            map.put("chiAddr",info.getChiAddr());
            map.put("slipNo",slipNo);
            map.put("count",count);
            map.put("vendor",vendor);
            map.put("deliveryDate",deliveryDate);
            excelWriter.fill(map,writeSheet);
            excelWriter.fill(new FillWrapper("t", list), fillConfig, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            log.error("导出外发加工单合同失败:{}", e.getMessage(),e);
            throw new ServiceErrorException("外发加工单导出失败!");
        }
    }

    /**
     * 导出明细
     * @param request
     * @param response
     */
    @Override
    public void ExportDetails(OutGoingQueryRequest request, HttpServletResponse response) {
        if (ObjectUtils.isEmpty(request.getOutDispatchType())){
            throw new ServiceErrorException("外发标记不能为空!");
        }
        UserInfoUtil.UserInfo userInfo = UserInfoUtil.getUserInfo();
        String loginName = userInfo.getLoginName();
        String companyId = userInfo.getCompanyId();
        List<PcOutListDetailDto> list = pcOutListMapper.getOutsourcedDetailsList(request, loginName, companyId);
        String fileName = "外发加工单" + DateUtils.dateTimeNow() + ".xls";
        if (request.getOutDispatchType()==3){
            getLotNoDetails(response, list, fileName);
        }else {
            getAllExport(response, list, fileName);
        }
    }

    /**
     * 导出指令外发明细
     * @param response
     * @param list
     * @param fileName
     */
    private void getLotNoDetails(HttpServletResponse response, List<PcOutListDetailDto> list, String fileName) {
        try (
                InputStream inputStream = new ClassPathResource("templates/外发明细模板.xls").getInputStream();
                OutputStream outputStream = response.getOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream).excelType(ExcelTypeEnum.XLS).withTemplate(inputStream).build();
        ) {
            ExcelUtils.setResponseZF(response, fileName);
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(new FillWrapper("t", list), fillConfig, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            throw new ServiceErrorException("外发加工单导出失败!");
        }
    }

    /**
     * 0 冲裁外发 1 工艺外发  2 补单外发
     * @param response
     * @param list
     * @param fileName
     */
    private void getAllExport(HttpServletResponse response, List<PcOutListDetailDto> list, String fileName) {
        try (
                InputStream inputStream = new ClassPathResource("templates/外发明细模板2.xls").getInputStream();
                OutputStream outputStream = response.getOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream).excelType(ExcelTypeEnum.XLS).withTemplate(inputStream).build();
        ) {
            ExcelUtils.setResponseZF(response, fileName);
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(new FillWrapper("t", list), fillConfig, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            throw new ServiceErrorException("外发加工单导出失败!");
        }
    }

    /**
     * 冲裁外发-选择部位工艺
     * @param request
     * @param flag
     * @return
     */
    @Override
    public ResponseInfo SelectPartProcess(LotNoRequest request, int flag) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        //查询指令信息
        PcLotHead pcLotHead = pcOutListMapper.getPcLotHead(request.getLotNo(), companyId);
        if (ObjectUtils.isEmpty(pcLotHead)) {
            return ResponseInfo.error("请输入正确的指令/型体!");
        }

        Integer count = pcStitchBarcodeHeadMapper.getPcCostLot(request.getLotNo(), companyId);
        if (count != null && count > 0) {
            return ResponseInfo.error(request.getLotNo() + "指令成本已封账,不能处理!");
        }
        String code=null;
        switch (flag) {
            case 0:
                code="01";
                break;
            case 1:
                code="02";
                break;
            default:
                return ResponseInfo.error("请选择正确的指令类型!");
        }
        List<PcLotOutListDto> list = pcOutListMapper.getPartProcess(request.getLotNo(), code,companyId);
        if (ObjectUtils.isEmpty(list)){
            return ResponseInfo.error("该指令下部位工艺未审核/不存在!");
        }
        Map map = new HashMap<>();
        List<PcLotOutListDto> dtoList=new ArrayList<>();
        for (PcLotOutListDto t : list) {
            String process = t.getProcess();
            String partName = t.getPartName();
            String[] part = partName.split(process);
            List<PcOutSizeListDto> sizeDetailList = pcOutListMapper.getSizeDetailList2(t.getLotNo(), t.getPartName(), t.getProcess(), code);
            if (!ObjectUtils.isEmpty(sizeDetailList)) {
                List<PcOutSizeListDto> sizeList=new ArrayList<>();
                for (PcOutSizeListDto pcOutSizeListDto : sizeDetailList) {
                    if (pcOutSizeListDto.getOrderQty()==null){
                       pcOutSizeListDto.setOrderQty(new BigDecimal(0));
                    }
                    if (pcOutSizeListDto.getOutQty()==null){
                        pcOutSizeListDto.setOutQty(new BigDecimal(0));
                    }
                    BigDecimal decimal = pcOutSizeListDto.getOrderQty().subtract(pcOutSizeListDto.getOutQty());
                    pcOutSizeListDto.setOutQty(decimal);
                    if (pcOutSizeListDto.getOutQty().compareTo(new BigDecimal(0))>0) {
                        pcOutSizeListDto.setThisQty(decimal);
                        sizeList.add(pcOutSizeListDto);
                    }
                }
                if (!ObjectUtils.isEmpty(sizeList)) {
                    t.setSizeList(sizeDetailList);
                    dtoList.add(t);
                }
            }
            t.setPartName(part[1]);
        }
        if (ObjectUtils.isEmpty(dtoList)){
            return ResponseInfo.error("该指令没有可外发的工艺!");
        } else {
            map.put(request.getLotNo(), dtoList);
            String photo = pcOutListMapper.getPhoto(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            map.put("photo", photo);
            return ResponseInfo.ok(map);
        }
    }

    /**
     * 查询补单号列表
     * @param request
     * @return
     */
    @Override
    public ResponseInfo SelectPartProcessQuery(LotNo2Request request) {
        if (ObjectUtils.isEmpty(request.getLotNo())&&ObjectUtils.isEmpty(request.getNewLotNo())){
            return ResponseInfo.error("指令或补料单号不能为空!");
        }
        List<PcLotHeadListDto> slipNoList = pcOutListMapper.getSlipNoList(request.getLotNo(), request.getNewLotNo());
        return ResponseInfo.ok(slipNoList);
    }

    /**
     * 补单-外加工项目选择外发指令查询
     * @param request
     * @return
     */
    @Override
    public ResponseInfo SupplementaryOrderSelectionOutsourcingInstruction(LotNo2Request request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getNewLotNo())) {
            return ResponseInfo.error("补料单号不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        Integer count = pcStitchBarcodeHeadMapper.getPcCostLot(request.getLotNo(), companyId);
        if (count != null && count > 0) {
            return ResponseInfo.error(request.getLotNo() + "指令成本已封账,不能处理!");
        }
        List<PcLotOutListDto> outPartName = pcOutListMapper.getOutPartName(request.getLotNo(),companyId,request.getNewLotNo());
        if (ObjectUtils.isEmpty(outPartName)) {
            return ResponseInfo.error("该指令补单的外加工项目未审核/已外发!");
        }
        Map map = new HashMap<>();
        List<PcLotOutListDto> dtoList = new ArrayList<>();
        //根据补单号码数量降序获取最大的数量的记录
        PcSupplementDetail slipNoOrderQty = pcOutListMapper.getSlipNoOrderQty(request.getLotNo(), request.getNewLotNo());
        if (ObjectUtils.isEmpty(slipNoOrderQty)) {
            return ResponseInfo.error("该指令补单没有数量明细!");
        }
        Float totalQty = slipNoOrderQty.getTotalQty();
        for (PcLotOutListDto t : outPartName) {
            t.setTotalQty(BigDecimal.valueOf(totalQty));
            t.setReqNo(request.getNewLotNo());
            List<PcOutSizeListDto> pcSupplementSize = pcOutListMapper.getPcSupplementSize(request.getLotNo(), request.getNewLotNo(), slipNoOrderQty.getSeqNo(),t.getPartName());
            List<PcOutSizeListDto> sizeList = new ArrayList<>();
            if (!ObjectUtils.isEmpty(pcSupplementSize)) {
                for (PcOutSizeListDto pcOutSizeListDto : pcSupplementSize) {
                    BigDecimal rQty = getRQty(slipNoOrderQty, Integer.valueOf(pcOutSizeListDto.getCutSize()));
                    if (pcOutSizeListDto.getOrderQty() != null) {
                        BigDecimal number = rQty.subtract(pcOutSizeListDto.getOrderQty());
                        pcOutSizeListDto.setOutQty(number);
                        pcOutSizeListDto.setThisQty(number);
                    } else {
                        pcOutSizeListDto.setOutQty(rQty);
                        pcOutSizeListDto.setThisQty(rQty);
                    }
                    if (pcOutSizeListDto.getOutQty() != null && pcOutSizeListDto.getOutQty().compareTo(BigDecimal.ZERO) > 0) {
                        sizeList.add(pcOutSizeListDto);
                    }
                }
            }
            if (!ObjectUtils.isEmpty(sizeList)) {
                t.setSizeList(sizeList);
                dtoList.add(t);
            }
        }
        if (ObjectUtils.isEmpty(dtoList)) {
            return ResponseInfo.error("该指令补单没有可外发的项目!");
        } else {
            map.put(request.getLotNo(), dtoList);
            PcLotHead pcLotHead = pcOutListMapper.getPcLotHead(request.getLotNo(), companyId);
            String photo = pcOutListMapper.getPhoto(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            map.put("photo", photo);
            return ResponseInfo.ok(map);
        }
    }

    /**
     * 开启反射获取值,统一获取左边的值
     * @param pcSupplementDetail
     * @return
     */
    private BigDecimal getRQty(PcSupplementDetail pcSupplementDetail,int i){
        try {
            Field lQty = PcSupplementDetail.class.getDeclaredField("lQty" + i);
            Field rQty = PcSupplementDetail.class.getDeclaredField("rQty" + i);
            lQty.setAccessible(true);
            rQty.setAccessible(true);
            Object lQtyValue = lQty.get(pcSupplementDetail);
            Object rQtyValue = rQty.get(pcSupplementDetail);
            if (lQtyValue instanceof Float && rQtyValue instanceof Float) {
                float sum = (Float) lQtyValue + (Float) rQtyValue;
                return BigDecimal.valueOf(sum / 2);
            }else {
                return null;
            }
        } catch (NoSuchFieldException | IllegalAccessException |ClassCastException e) {
            log.error("反射字段失败:{}",e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 部位补单外发明细
     * @param request
     * @return
     */
    @Override
    public ResponseInfo PartReplacementOrderOutsourcing(LotNo2Request request) {
        if (ObjectUtils.isEmpty(request.getLotNo())) {
            return ResponseInfo.error("指令不能为空!");
        }
        if (ObjectUtils.isEmpty(request.getNewLotNo())) {
            return ResponseInfo.error("补料单号不能为空!");
        }
        String companyId = UserIdThread.get().getCompanyId();
        Integer count = pcStitchBarcodeHeadMapper.getPcCostLot(request.getLotNo(), companyId);
        if (count != null && count > 0) {
            return ResponseInfo.error(request.getLotNo() + "指令成本已封账,不能处理!");
        }
        List<PcLotOutListDto> silpProcessList = pcOutListMapper.getSilpProcessList(request.getLotNo(), request.getNewLotNo());
        if (ObjectUtils.isEmpty(silpProcessList)) {
            return ResponseInfo.error("该指令补单外发工艺未审核!");
        }
        Map map = new HashMap<>();
        List<PcLotOutListDto> dtoList = new ArrayList<>();
        for (PcLotOutListDto t : silpProcessList) {
            String process = t.getProcess();
            String partName = t.getPartName();
            String[] part = partName.split(process);
            List<PcSupplementDetail> slipNoOrderQty = pcOutListMapper.getSlipNoOrderQty2(request.getLotNo(), request.getNewLotNo(), part[1]);
            List<PcOutSizeListDto> sizeList = new ArrayList<>();
            for (PcSupplementDetail pcSupplementDetail : slipNoOrderQty) {
                List<PcOutSizeListDto> pcSupplementSize = pcOutListMapper.getPcSupplementSize2(request.getLotNo(), request.getNewLotNo(), pcSupplementDetail.getSeqNo(), part[1]);
                for (PcOutSizeListDto pcOutSizeListDto : pcSupplementSize) {
                    BigDecimal rQty = getRQty(pcSupplementDetail, Integer.valueOf(pcOutSizeListDto.getCutSize()));
                    if (pcOutSizeListDto.getOrderQty() != null) {
                        BigDecimal number = rQty.subtract(pcOutSizeListDto.getOrderQty());
                        pcOutSizeListDto.setOutQty(number);
                        pcOutSizeListDto.setThisQty(number);
                    } else {
                        pcOutSizeListDto.setOutQty(rQty);
                        pcOutSizeListDto.setThisQty(rQty);
                    }
                    if (pcOutSizeListDto.getOutQty() != null && pcOutSizeListDto.getOutQty().compareTo(BigDecimal.ZERO) > 0) {
                        sizeList.add(pcOutSizeListDto);
                    }
                }
            }
            if (!ObjectUtils.isEmpty(sizeList)) {
                t.setSizeList(sizeList);
                dtoList.add(t);
            }
        }
        if (ObjectUtils.isEmpty(dtoList)) {
            return ResponseInfo.error("该指令补单没有可外发的部位工艺!");
        } else {
            map.put(request.getLotNo(), dtoList);
            PcLotHead pcLotHead = pcOutListMapper.getPcLotHead(request.getLotNo(), companyId);
            String photo = pcOutListMapper.getPhoto(pcLotHead.getStyle(), pcLotHead.getColor(), companyId);
            map.put("photo", photo);
            return ResponseInfo.ok(map);
        }
    }
}